﻿using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Xml;
using System.Collections;
using System.Data;
using System.Diagnostics;

namespace Data
{
 
    public struct REALPOINT
    {
        Double tdx;
        public Double x
        {
            get { return tdx; }
            set { tdx = value; }
        }
        Double tdy;
        public Double y
        {
            get { return tdy; }
            set { tdy = value; }
        }
        public REALPOINT(Double x1, Double y1)
        {
            tdx = x1;
            tdy = y1;
        }
    }
 
    public class CPoint3D
    {
        
       private Point3D vert;
       public bool m_bEndCont;
     

      public Double MAX(Double a, Double b)
       {
           return a > b ? a : b;
       }
      public Double MIN(Double a, Double b)
       {
           return a < b ? a : b;
       }
      public int round(Double x)
       {
           // Ham lam tron so Double sang integer
           int i = (int)(x);
           Double d = x - (Double)i;
           if (d > 0.5) i++;
           return i;
       }
    
      public bool exist_node_real(List<REALPOINT> l, REALPOINT p)
       {
           for (int i = 0; i < l.Count; i++)
           {
               if (p.x == l[i].x && p.y == l[i].y)
                   return true;
           }
           return false;
       }

      public Double Max_MinList(List<REALPOINT> l, int XY, int MinMax)
       {
           // ham tinh min max :
           /*
              XY= 1(true) :Neu gia ti can tim la X
              XY= 0(false) :Neu gia ti can tim la Y
              MinMax =1 :Gia tri tra ve la maximum
              MinMax=0 : Gia tri tra ve la minimum          
           */
           Double ret = 0;
           //REALPOINT temp;
           int count = l.Count;
           if (XY == 1)// tim gia tri x
           {
               ret = l[0].x;

               if (MinMax == 1)//tinh gia tri max cua x
               {
                   for (int i = 1; i < count; i++)
                   {

                       if (ret < l[i].x)
                           ret = l[i].x;
                   }
               }
               else//tinh gia tri min cua x
               {
                   for (int i = 1; i < count; i++)
                   {

                       if (ret > l[i].x)
                           ret = l[i].x;
                   }
               }
           }
           else//Tim gia tri y
           {

               ret = l[0].y;
               if (MinMax == 1)
               {//tinh gia tri min cua y
                   for (int i = 1; i < count; i++)
                   {

                       if (ret < l[i].y)
                           ret = l[i].y;
                   }
               }
               else
               {//tinh gia tri min cua y 
                   for (int i = 1; i < count; i++)
                   {
                       if (ret > l[i].y)
                           ret = l[i].y;
                   }
               }

           }
           return ret;
       }
      public bool OnEdge(REALPOINT a, REALPOINT p1, REALPOINT p2)
       {
           if (a.x >= MIN(p1.x, p2.x) && a.x <= MAX(p1.x, p2.x) && a.y <= MAX(p1.y, p2.y) && a.y >= MIN(p1.y, p2.y))
           {
               Double y1y2 = p1.y - p2.y;
               Double x1x2 = p1.x - p2.x;
               Double result = (a.x - p1.x) * y1y2 - (a.y - p1.y) * x1x2;
               if (result == 0)
                   return true;
               else return false;
           }
           return false;
       }
      public  int InsidePolygon(List<REALPOINT> polygon, REALPOINT p)
       {
           int INSIDE = 0;
           int OUTSIDE = 1;
           int counter = 0;
           int i;
           Double xinters;
           int N = polygon.Count;
           REALPOINT p1, p2;
           p1 = new REALPOINT(polygon[0].x, polygon[0].y);
           for (i = 1; i <= N; i++)
           {
               p2 = new REALPOINT(polygon[i % N].x, polygon[i % N].y);
               if (OnEdge(p, p1, p2) == true)
                   return OUTSIDE;//loai bo cac diem bien
               if (p.y > MIN(p1.y, p2.y))
               {
                   if (p.y <= MAX(p1.y, p2.y))
                   {
                       if (p.x <= MAX(p1.x, p2.x))
                       {
                           if (p1.y != p2.y)
                           {
                               xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
                               if (p1.x == p2.x || p.x <= xinters)
                                   counter++;
                           }
                       }
                   }
               }
               p1 = p2;
           }
           int iii = 0;
           if (counter % 2 == 0)
               return (OUTSIDE);
           else
               return (INSIDE);

       }
      public Point3D vertex
       {
           get { return vert; }
           set { vert = value; }
       }
      public CPoint3D()
      {
          vert = new Point3D();
          m_bEndCont = false;
      }
      public CPoint3D(Point3D p)
      {
          vert = p;
          m_bEndCont = false;
      }
        
     
      void SetEndCont(bool bEndCont)
      {
          m_bEndCont = bEndCont;
      }
      bool IsEndCont()
      {
          return m_bEndCont;
      }
      public string ToString()
      {
          return vertex.X.ToString() + "," + vertex.Y.ToString() + "," + vertex.Z.ToString();
      }
    /*
     public void SortXIncre(List<REALPOINT> a)
      {
          for (int i = 0; i < a.Count; i++)
          {
              for (int j = 0; j < a.Count; j++)
              {
                  if (a[i].x < a[j].x)
                  {
                      REALPOINT temp;
                      temp = a[i];
                      a[i] = a[j];
                      a[j] = temp;

                  }
              }
          }
      }
     public void SortXDecre(List<REALPOINT> a)
     {
         for (int i = 0; i < a.Count; i++)
         {
             for (int j = 0; j < a.Count; j++)
             {
                 if (a[i].x > a[j].x)
                 {
                     REALPOINT temp;
                     temp = a[i];
                     a[i] = a[j];
                     a[j] = temp;

                 }
             }
         }
     }
     public void SortYIncre(List<REALPOINT> a)
     {
         for (int i = 0; i < a.Count; i++)
         {
             for (int j = 0; j < a.Count; j++)
             {
                 if (a[i].y < a[j].y)
                 {
                     REALPOINT temp;
                     temp = a[i];
                     a[i] = a[j];
                     a[j] = temp;

                 }
             }
         }
     }
     public void SortYDecre(List<REALPOINT> a)
     {
         for (int i = 0; i < a.Count; i++)
         {
             for (int j = 0; j < a.Count; j++)
             {
                 if (a[i].y > a[j].y)
                 {
                     REALPOINT temp;
                     temp = a[i];
                     a[i] = a[j];
                     a[j] = temp;

                 }
             }
         }
     }   
     */
      public void SortXIncre(List<Point3D> a)
      {
          for (int i = 0; i < a.Count; i++)
          {
              for (int j = 0; j < a.Count; j++)
              {
                  if (a[i].X < a[j].X)
                  {
                      Point3D temp=new Point3D();
                      temp = a[i];
                      a[i] = a[j];
                      a[j] = temp;

                  }
              }
          }
      }
      public void SortXDecre(List<Point3D> a)
      {
          for (int i = 0; i < a.Count; i++)
          {
              for (int j = 0; j < a.Count; j++)
              {
                  if (a[i].X > a[j].X)
                  {
                      Point3D temp = new Point3D();
                      temp = a[i];
                      a[i] = a[j];
                      a[j] = temp;

                  }
              }
          }
      }
      public void SortYIncre(List<Point3D> a)
      {
          for (int i = 0; i < a.Count; i++)
          {
              for (int j = 0; j < a.Count; j++)
              {
                  if (a[i].Y < a[j].Y)
                  {
                      Point3D temp=new Point3D();
                      temp = a[i];
                      a[i] = a[j];
                      a[j] = temp;

                  }
              }
          }
      }
      public void SortYDecre(List<Point3D> a)
      {
          for (int i = 0; i < a.Count; i++)
          {
              for (int j = 0; j < a.Count; j++)
              {
                  if (a[i].Y > a[j].Y)
                  {
                      Point3D temp = new Point3D();
                      temp = a[i];
                      a[i] = a[j];
                      a[j] = temp;

                  }
              }
          }
      }    
    }
   
   
}
